package homework7.soso.untils;

import homework7.soso.entity.*;
import homework7.soso.service.impl.NetPackage;
import homework7.soso.service.impl.ServicePackage;
import homework7.soso.service.impl.SuperPackage;
import homework7.soso.service.impl.TalkPackage;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;


/**
 * @author fengq
 * 操作卡的工具类
 */
public class CardUtil {
    /**
     * 初始化套餐
     */
    public final static ServicePackage[] SERVE = new ServicePackage[3];
    static {
        SERVE[0] = new TalkPackage(500, 30, 58);
        SERVE[1] = new SuperPackage(200, 50, 1, 78);
        SERVE[2] = new NetPackage(3, 68);

    }

    /**
     * 初始化场景信息
     */
    public final static Scene[] SCENE = new Scene[6];
    static {
        SCENE[0] = new Scene("通话", 90, "问候客户冯驴TM，没想到这斯如此难缠，通话90分钟");
        SCENE[1] = new Scene("通话", 30, "询问冯驴被雷劈后的身体状况，本地通话30分钟");
        SCENE[2] = new Scene("短信", 5, "询问仲恺的同学养驴的情况问卷调查，发送短信5条");
        SCENE[3] = new Scene("短信", 50, "避免冯驴的干扰，换手机号并通知朋友手机换号，发送信息50条");
        SCENE[4] = new Scene("上网", 1, "和女朋友微信视频聊天3句话，使用流量1GB");
        SCENE[5] = new Scene("上网", 2, "晚上手机在线看雷剧刘狗大战冯驴巨作，不留神睡着了！使用流量2GB");
    }

    /**
     * 已注册的嗖嗖移动用户列表
     */
    public Map<String, MobileCard> cards = new HashMap<>();

    /**
     * 记录用户消费记录的
     */
    public ArrayList<ConsumeInfo> arrayList = new ArrayList<>();

    /**
     * 所有卡号的消费记录列表
     */
    public Map<String, ArrayList<ConsumeInfo>> consumeInfos = new HashMap<String, ArrayList<ConsumeInfo>>();

    Scanner input = new Scanner(System.in);

    /**
     * 构造函数
     */
    @SuppressWarnings("unchecked")
    public CardUtil() {
        ObjectInputStream objectInputStream = null;
        try {
            File file=new File("D:\\Message.txt");
            if (file.length()!=0){
                FileInputStream fileInputStream = new FileInputStream(file);
                objectInputStream = new ObjectInputStream(fileInputStream);
                cards = (Map<String, MobileCard>) objectInputStream.readObject();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (objectInputStream != null) {
                try {
                    objectInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }




    /**
     * 根据卡号密码验证卡是否注册
     * @param number
     * @param passWord
     * @return
     */
    public boolean isExistCard(String number,String passWord) {
        if (cards.containsKey(number)) {
            if (passWord.equals(cards.get(number).getPassword())) {
                System.out.println("登录成功");
                return true;
            }else {
                System.out.println("密码错误");
                return false;
            }
        }
        else {
            System.out.println("手机卡号错误");
            return false;
        }
    }


    /**
     * 根据卡号验证卡是否注册
     * @param number
     * @return
     */
    public boolean isExistCard(String number) {
        if (cards.containsKey(number)) {
            return true;
        } else {
            System.out.println("该手机号不存在");
            return false;
        }
    }




    /**
     * 注册新卡
     * @param card
     */
    public void addCard(MobileCard card) {
        String number = NumberUtil.createNumber(cards,input);
        System.out.println(" 1. 话痨套餐"+"\t" +"2. 超人套餐"+"\t" +"3. 网虫套餐,"+"\t" +"请选择套餐(输入序号):");
        int order;
        do {
            if (input.hasNextInt()) {
                order = input.nextInt();
                if (order < 4 && order > 0) {
                    break;
                } else {
                    System.out.println("没有该种套餐，请重新输入");
                }
            } else {
                System.out.println("输入错误指令，请重新输入");
                input.next();
            }
        } while (true);
        //选择对应的套餐
        card.setServicePackage(SERVE[order - 1]);
        System.out.println("请输入姓名");
        String name = input.next();
        System.out.println("请输入密码");
        String passwod = input.next();
        System.out.println("请输入预存话费金额");
        double money;
        do {
            do {
                if (input.hasNextDouble()) {
                    money = input.nextDouble();
                    break;
                } else {
                    System.out.println("输入有误，请重新输入");
                    input.next();
                }
            } while (true);

            if (money >= card.getServicePackage().price) {
                //设置消费金额和账户余额
                card.setMoney(money - card.getServicePackage().price);
                card.setConsumeAmount(card.getConsumeAmount() + card.getServicePackage().price);
                break;
            } else {
                System.out.println("您预存的话费金额不足以支付本月固定套餐资费，请重新充值");
            }
        } while (true);
        //初始化卡号信息
        card.setCardNumber(number);
        card.setUserName(name);
        card.setPassword(passwod);
        //存入集合
        cards.put(number, card);
        //显示卡号信息
        System.out.println("注册成功！");
        System.out.println("卡号：" + number + " 用户名:" + name + "当前余额:" + NumberUtil.dataFormat(card.getMoney()) + "元");
        card.getServicePackage().showInfo();

    }

    /**
     * 套餐余量查询
     * @param number
     */
    public void showRemainDetail(String number) {
        int remainTalkTime;
        int remainSmsCount;
        int remainFlow;
        ServicePackage servicePackage = cards.get(number).getServicePackage();
        System.out.println("***********套餐余量查询***********");
        System.out.println("您的卡号是 " + number + "套餐内剩余");
        if (servicePackage instanceof TalkPackage) {
            TalkPackage talkPackage = (TalkPackage) servicePackage;
            remainSmsCount = talkPackage.getSmsCount() > cards.get(number).getRealSMSCount() ? talkPackage.getSmsCount() - cards.get(number).getRealSMSCount() : 0;
            remainTalkTime = talkPackage.getTalkTime() > cards.get(number).getRealTalkTime() ? talkPackage.getTalkTime() - cards.get(number).getRealTalkTime() : 0;
            System.out.println("通话时长" + remainTalkTime + "分钟");
            System.out.println("短信条数" + remainSmsCount + "条");
        } else if (servicePackage instanceof SuperPackage) {
            SuperPackage superPackage = (SuperPackage) servicePackage;
            remainSmsCount = superPackage.getSmsCount() > cards.get(number).getRealSMSCount() ? superPackage.getSmsCount() - cards.get(number).getRealSMSCount() : 0;
            remainTalkTime = superPackage.getTalkTime() > cards.get(number).getRealTalkTime() ? superPackage.getTalkTime() - cards.get(number).getRealTalkTime() : 0;
            remainFlow = superPackage.getFlow() > cards.get(number).getRealFlow() ? superPackage.getFlow() - cards.get(number).getRealFlow() : 0;
            System.out.println("通话时长" + remainTalkTime + "分钟");
            System.out.println("短信条数" + remainSmsCount + "条");
            System.out.println("上网流量" + remainFlow + "GB");
        } else if (servicePackage instanceof NetPackage) {
            NetPackage netPackage = (NetPackage) servicePackage;
            remainFlow = netPackage.getFlow() > cards.get(number).getRealFlow() ? netPackage.getFlow() - cards.get(number).getRealFlow() : 0;
            System.out.println("上网流量" + remainFlow);
        }
    }

    /**
     * 本月账单查询
     * @param number
     */
    public void showAmountDetail(String number) {//本月账单查询
        cards.get(number).showMeg();
    }

    /**
     * 添加指定卡号的消费记录
     * @param number
     * @param info
     */
    public void addConsumeInfo(String number, ConsumeInfo info) {
        //cards = test();//测试用
        if (consumeInfos.containsKey(number)) {
            consumeInfos.get(number).add(info);
            System.out.println("成功添加一条消费记录");
        } else {
            arrayList.add(info);
            consumeInfos.put(number, arrayList);
            System.out.println("不存在此卡的消费记录，已添加一条消费记录");
        }
    }

    /**
     * 使用嗖嗖
     * @param number
     */
    public void useSoso(String number) {
        ServicePackage servicePackage = cards.get(number).getServicePackage();
        TalkPackage talkPackage;
        SuperPackage superPackage;
        Random random = new Random();
        int a;
        int use = 0;

        do {
            a = random.nextInt(6);
            switch (a) {
                case 0:

                case 1:
                    //电话
                    if (servicePackage instanceof TalkPackage) {
                        talkPackage = (TalkPackage) servicePackage;
                        System.out.println(SCENE[a].getDescription());
                        try {
                            use = talkPackage.call(SCENE[a].getData(), cards.get(number));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }//调用call方法
                        if (use == 0) {
                            use = (int) cards.get(number).getMoney();
                            cards.get(number).setMoney(0);
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));

                        } else {
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));
                        }
                    } else if (servicePackage instanceof SuperPackage) {
                        superPackage = (SuperPackage) servicePackage;
                        System.out.println(SCENE[a].getDescription());
                        try {
                            use = superPackage.call(SCENE[a].getData(), cards.get(number));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (use == 0) {
                            use = (int) cards.get(number).getMoney();
                            cards.get(number).setMoney(0);
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));

                        } else {
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));
                        }

                        break;
                    } else {
                        //该卡套餐不支持通话功能，重新生成随机数。
                        continue;
                    }

                    break;
                case 2:

                case 3:     //短信
                    if (servicePackage instanceof TalkPackage) {
                        talkPackage = (TalkPackage) servicePackage;
                        System.out.println(SCENE[a].getDescription());
                        try {
                            use = talkPackage.send(SCENE[a].getData(), cards.get(number));
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }//调用call方法
                        if (use == 0) {
                            use = (int) cards.get(number).getMoney();
                            cards.get(number).setMoney(0);
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));

                        } else {
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));
                        }
                    } else if (servicePackage instanceof SuperPackage) {
                        superPackage = (SuperPackage) servicePackage;
                        System.out.println(SCENE[a].getDescription());
                        try {
                            use = superPackage.send(SCENE[a].getData(), cards.get(number));
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        //addConsumeInfo(number,scene[a].getType(),use);
                        if (use == 0) {
                            use = (int) cards.get(number).getMoney();
                            cards.get(number).setMoney(0);
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));

                        } else {
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));
                        }
                    } else {
                        //该卡套餐不支持通话功能，重新生成随机数。
                        continue;
                    }
                    break;
                case 4:


                case 5://上网
                    if (servicePackage instanceof NetPackage) {
                        NetPackage netPackage2 = (NetPackage) servicePackage;
                        System.out.println(SCENE[a].getDescription());
                        try {
                            use = netPackage2.netPlay(SCENE[a].getData(), cards.get(number));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (use == 0) {
                            use = (int) cards.get(number).getMoney();
                            cards.get(number).setMoney(0);
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));

                        } else {
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));
                        }
                    } else if (servicePackage instanceof SuperPackage) {
                        superPackage = (SuperPackage) servicePackage;
                        System.out.println(SCENE[a].getDescription());
                        try {
                            use = superPackage.netPlay(SCENE[a].getData(), cards.get(number));
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        if (use == 0) {
                            use = (int) cards.get(number).getMoney();
                            cards.get(number).setMoney(0);
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));

                        } else {
                            addConsumeInfo(number, new ConsumeInfo(number, SCENE[a].getType(), use));
                        }
                    } else {
                        //该卡套餐不支持通话功能，重新生成随机数。
                        continue;
                    }
            }
            break;
        } while (true);
    }

    /** 
     * 输出指定卡号消费记录 
     * @param number
     */
    public void printConsumeInfo(String number) {
        OutputStream outputStream;
        BufferedWriter bufferedWriter;
        try {
            if (consumeInfos.containsKey(number)) {
                int i = 0;
                if (consumeInfos.get(number) != null) {
                    String property = System.getProperty("user.dir");
                    outputStream = new FileOutputStream(property+"/src/sosoServer/" + number + "消费记录.txt");
                    bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
                    Iterator<ConsumeInfo> iterator = consumeInfos.get(number).iterator();
                    while (iterator.hasNext()) {
                        ConsumeInfo ConsumeInfo = iterator.next();
                        i++;
                        if (ConsumeInfo.getType().equals("上网")) {
                            bufferedWriter.write(i + "." + ConsumeInfo.getType() + ConsumeInfo.getConsumeData() + "MB");
                            bufferedWriter.write("\n");
                            bufferedWriter.flush();
                        } else if (ConsumeInfo.getType().equals("短信")) {
                            bufferedWriter.write(i + "." + ConsumeInfo.getType() + ConsumeInfo.getConsumeData() + "条");
                            bufferedWriter.write("\n");
                            bufferedWriter.flush();
                        } else {
                            bufferedWriter.write(i + "." + ConsumeInfo.getType() + ConsumeInfo.getConsumeData() + "分钟");
                            bufferedWriter.write("\n");
                            bufferedWriter.flush();
                        }
                    }
                    System.out.println("消费记录打印完毕！");
                    bufferedWriter.close();
                    outputStream.close();
                } else {
                    System.out.println("对不起，不存在此号码的消费记录，不能打印!");
                }
            } else {
                System.out.println("对不起，不存在此号码的消费不能打印，不能打印!");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 输出套餐资费描述
     */
    public void showDescription() {
        try {
            InputStream inputStream = new FileInputStream("D:\\Description.txt");
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = bufferedReader.readLine();
            while (line != null) {
                System.out.println(line);
                line = bufferedReader.readLine();
            }
            bufferedReader.close();
            inputStream.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 套餐变更
     * @param number
     */
    public void changingPack(String number) {
        System.out.println("********套餐变更*********");
        System.out.println("1.话痨套餐" + "\t" + "2.超人套餐" + "\t" + "3.网虫套餐," + "\t" + "请选择套餐(输入序号):");
        int digit;
        do {
            if (input.hasNextInt()) {
                digit = input.nextInt();
                if (digit < 4 && digit > 0) {
                    break;
                } else {
                    System.out.println("没有该种套餐，请重新输入");
                }
            } else {
                System.out.println("输入错误指令，请重新输入");
                input.next();
            }
        } while (true);
        if (digit == 1) {
            if (cards.get(number).getServicePackage() instanceof TalkPackage) {
                System.out.println("对不起，您已经是该卡套餐用户，无需更换！");
            } else if (cards.get(number).getMoney() < 58) {
                System.out.println("对不起，您的余额不足以支付新套餐本月资费，请充值后在办理更换套餐业务！");
            } else {
                cards.get(number).setRealFlow(0);
                cards.get(number).setRealTalkTime(0);
                cards.get(number).setRealSMSCount(0);
                cards.get(number).setServicePackage(SERVE[digit - 1]);
                cards.get(number).setMoney(cards.get(number).getMoney() - SERVE[digit - 1].price);
                cards.get(number).setConsumeAmount(SERVE[digit - 1].price);
                System.out.println("套餐变更成功! 话痨套餐：通话时长500分钟/ 月，短信条数为30条/月，资费为58.0/月.");
            }

        } else if (digit == 2) {
            if (cards.get(number).getServicePackage() instanceof SuperPackage) {
                System.out.println("对不起，您已经是该卡套餐用户，无需更换！");
            } else if (cards.get(number).getMoney() < 78) {
                System.out.println("对不起，您的余额不足以支付新套餐本月资费，请充值后在办理更换套餐业务！");
            } else {
                cards.get(number).setRealFlow(0);
                cards.get(number).setRealTalkTime(0);
                cards.get(number).setRealSMSCount(0);
                cards.get(number).setServicePackage(SERVE[digit - 1]);
                cards.get(number).setMoney(cards.get(number).getMoney() - SERVE[digit - 1].price);
                cards.get(number).setConsumeAmount(SERVE[digit - 1].price);
                System.out.println("套餐变更成功! 超人套餐：通话时长200分钟/ 月，上网流量1GB/月，短信条数为50条/月，资费为78.0/月.");
            }
        } else {
            if (cards.get(number).getServicePackage() instanceof NetPackage) {
                System.out.println("对不起，您已经是该卡套餐用户，无需更换！");
            } else if (cards.get(number).getMoney() < 68) {
                System.out.println("对不起，您的余额不足以支付新套餐本月资费，请充值后在办理更换套餐业务！");
            } else {
                cards.get(number).setRealFlow(0);
                cards.get(number).setRealTalkTime(0);
                cards.get(number).setRealSMSCount(0);
                cards.get(number).setServicePackage(SERVE[digit - 1]);
                cards.get(number).setMoney(cards.get(number).getMoney() - SERVE[digit - 1].price);
                cards.get(number).setConsumeAmount(SERVE[digit - 1].price);
                System.out.println("套餐变更成功! 网虫套餐：上网流量3GB/月，资费为68.0/月.");
            }
        }
    }

    /**
     * 话费充值
     * @param number
     */
    public void chargeMoney(String number) {
        if (cards.containsKey(number)) {
            System.out.println("请输入充值金额");
            double money;
            do {
                do {
                    if (input.hasNextDouble()) {
                        money = input.nextDouble();
                        break;
                    } else {
                        System.out.println("输入无效字符，请重新输入");
                        input.next();
                    }
                } while (true);
                if (money >= 50) {
                    cards.get(number).setMoney(cards.get(number).getMoney() + money);
                    System.out.println("充值成功,当前话费余额为" + NumberUtil.dataFormat(cards.get(number).getMoney()) + "元");
                    break;
                } else {
                    System.out.println("最少充值50元，请重新充值");
                }
            } while (true);
        }
    }

    /**
     * 删除卡
     * @param number
     */
    public void delCard(String number) {
        System.out.println("办理退网");
        String property = System.getProperty("user.dir");
        File file = new File(property+"/src/sosoServer/" + number + "消费记录.txt");
        if (file.exists())    //删除要退网的为用户的文件
        {
            file.delete();
        }
        cards.remove(number);
        System.out.println("卡号" + number + "办理退网成功!");
        System.out.println("谢谢使用");

    }

    /**
     * 退出系统并且保存当前系统用户的信息
     */
    public void exit() {
        ObjectOutputStream objectOutputStream = null;
        try {
            objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\Message.txt"));
            objectOutputStream.writeObject(cards);
            objectOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                objectOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}